package com.microlecture.controller;

import com.microlecture.common.Constants;
import com.microlecture.common.DataPacket;
import com.microlecture.entity.UserEntity;
import com.microlecture.service.SendMailService;
import com.microlecture.service.UserService;
import com.microlecture.utils.LoginUtils;
import com.microlecture.utils.PasswordUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * 用户控制
 * Created by 孙志伟 on 2018/4/27.
 */
@Controller
public class UmsController {

    private static final Logger LOG = LoggerFactory.getLogger(UmsController.class);

    /**
     * 登录
     * @return
     */
    @RequestMapping("/login")
    public String login() {
        return "login";
    }

    /**
     * 注册
     * @return
     */
    @RequestMapping("/register")
    public String register() {
        return "register";
    }

    /**
     * 注册激活码
     * @return
     */
    @RequestMapping("/registerActivate")
    public String registerActivate() {
        return "registerActivate";
    }

    /**
     * 重置密码
     * @return
     */
    @RequestMapping("/resetPassword")
    public String resetPassword() {
        return "resetPassword";
    }

    /**
     * 重置密码激活码
     * @return
     */
    @RequestMapping("/resetActivate")
    public String resetActivate() {
        return "resetActivate";
    }

    /**
     * 登录
     * @return
     */
    @RequestMapping("/loginAction")
    @ResponseBody
    public Map<String, Object> loginAction(
            HttpSession session,
            @RequestParam("loginName")String loginName,
            @RequestParam("password")String password) {
        //加密-与数据库做匹配
        UsernamePasswordToken token = new UsernamePasswordToken(loginName, password);
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(token);
            return DataPacket.jsonResult();
        } catch (Exception e) {
            return DataPacket.errorJsonResult();
        }
    }

    @Autowired
    UserService userService;

    /**
     * 用户是不是存在
     * @param loginName
     * @return
     */
    private boolean isExistUser(String loginName) {
        UserEntity existUser = userService.queryByLoginName(loginName);
        if(existUser == null) {
            return false;
        } else {
            return true;
        }
    }

    @Autowired
    EhCacheManager ehCacheManager;

    @Autowired
    SendMailService sendMailService;

    private final String ACTIVATE_CACHE = "activateCache";

    /**
     * 发送注册激活码
     * @return
     */
    @RequestMapping("/sendActivateCode")
    @ResponseBody
    public Map<String, Object> sendActivateCode(
            @RequestParam("loginName") String loginName,
            @RequestParam("password") String password,
            @RequestParam("nick") String nick,
            @RequestParam("headImg") String headImg) {

        UserEntity userEntity = new UserEntity();
        userEntity.setLoginName(loginName);
        userEntity.setPassword(password);
        userEntity.setNick(nick);
        userEntity.setHeadimg(headImg);
        userEntity.setRole(Constants.ROLE_STUDENT);

        //是否存在
        if(isExistUser(userEntity.getLoginName())) {
            return DataPacket.jsonCode(DataPacket.APP_EXIST_USER_CODE);
        }
        PasswordUtils.encryptPassword(userEntity);
        Random random = new Random();
        String activateCode = String.valueOf(100000 + random.nextInt(99999));
        Cache<Object, Object> activateCache = ehCacheManager.getCache(ACTIVATE_CACHE);
        activateCache.put(activateCode, userEntity);
        Map<String, Object> model = new HashMap<>();
        model.put("activateCode", activateCode);
        new Thread(new Runnable() {
            @Override
            public void run() {
                //发送邮件
                try {
                    sendMailService.registerActivateCodeMail(userEntity.getLoginName(), model);
                } catch (Exception e) {
                    LOG.error("发送注册激活码出现问题" + e);
                }
            }
        }).start();
        return DataPacket.jsonResult();

    }



    /**
     * 注册时响应
     * @return
     */
    @RequestMapping("/registerAction")
    @ResponseBody
    public Map<String, Object> registerAction(@RequestParam("activateCode") String activateCode) {
        Cache<Object, Object> cache = ehCacheManager.getCache(ACTIVATE_CACHE);
        UserEntity userCache = (UserEntity) cache.get(activateCode);
        //激活码失效
        if(userCache == null) {
            return DataPacket.errorJsonResult();
        }
        //清除缓存
        cache.remove(activateCode);
        return DataPacket.changeDBResult(userService.insertSelective(userCache));
    }

    /**
     * 忘记密码激活码
     * @return
     */
    @RequestMapping("/forgetPasswordActivateCode")
    @ResponseBody
    public Map<String, Object> forgetPasswordActivateCode(
            @RequestParam("loginName") String loginName,
            @RequestParam("password") String password) {

        UserEntity userEntity = new UserEntity();
        userEntity.setLoginName(loginName);
        userEntity.setPassword(password);

        PasswordUtils.encryptPassword(userEntity);
        Random random = new Random();
        String activateCode = String.valueOf(100000 + random.nextInt(99999));
        Cache<Object, Object> activateCache = ehCacheManager.getCache(ACTIVATE_CACHE);
        activateCache.put(activateCode, userEntity);
        Map<String, Object> model = new HashMap<>();
        model.put("activateCode", activateCode);
        new Thread(new Runnable() {
            @Override
            public void run() {
                //发送邮件
                try {
                    sendMailService.activateCodeMail(userEntity.getLoginName(), model);
                } catch (Exception e) {
                    LOG.error("用户：" + loginName + "\n发送忘记密码激活码邮件出现问题\n" + e);
                }
            }
        }).start();
        return DataPacket.jsonResult();

    }

    /**
     * 忘记密码时响应
     * @return
     */
    @RequestMapping("/forgetPassword")
    @ResponseBody
    public Map<String, Object> forgetPassword(@RequestParam("activateCode") String activateCode) {
        Cache<Object, Object> cache = ehCacheManager.getCache(ACTIVATE_CACHE);
        UserEntity userCache = (UserEntity) cache.get(activateCode);
        if(userCache == null) {
            return DataPacket.errorJsonResult();
        }
        UserEntity currentUserInfo = userService.queryByLoginName(userCache.getLoginName());
        if(currentUserInfo == null) {
            return DataPacket.errorJsonResult();
        }
        userCache.setId(currentUserInfo.getId());
        //激活码失效
        if(userCache == null) {
            return DataPacket.errorJsonResult();
        }
        //清除缓存
        cache.remove(activateCode);
        return DataPacket.changeDBResult(userService.updateByPrimaryKeySelective(userCache));
    }

    @RequestMapping("/userInfo")
    public String userInfo(Model model) {
        UserEntity userEntity = userService.selectByPrimaryKey(LoginUtils.getCurrentUserInfo().getId());
        model.addAttribute("userInfo", userEntity);
        return "userInfo";
    }

    /**
     * 保存用户信息
     * @param nick
     * @param headImg
     * @return
     */
    @RequestMapping("/saveUserInfo")
    @ResponseBody
    public Map<String, Object> saveUserInfo(
            @RequestParam("nick") String nick,
            @RequestParam("headImg") String headImg) {
        if(LoginUtils.isSessionInvalid()) {
            return DataPacket.sessionInvalidJsonResult();
        }
        UserEntity currentUserInfo = LoginUtils.getCurrentUserInfo();
        currentUserInfo.setNick(nick);
        currentUserInfo.setHeadimg(headImg);
        return DataPacket.changeDBResult(userService.updateByPrimaryKeySelective(currentUserInfo));
    }

}
